home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
SCLIB.ARJ
/
SCL1SAMP.EXE
/
BMPCNV.C
< prev
next >
Wrap
Text File
|
1992-01-01
|
11KB
|
414 lines
/************************************************************************
This file reads a bitmap file (BMP) and creates a series of character
definition that make possible to display the bitmap in text mode
using SCL1 ModifyCharSet function.
Horizontally the bitmap size in bits must a multiple (in pixels) of 8 and
of 16, 14 or 8 vertically depending of target monitor. The bitmap
can be displayed using the /D switch. The total number of characters
must be < than 32 (64 pixels x 64 is a good size). Run with /? switch
for more information.
Bitmaps can be created using Windows's Paintbrush. Use the Options Menu
Image Attributes to set size in pixels and 16 colors. Use only pure white
and black colors.
Several BMP files are included. Files that start with VGA are for VGA
and the ones that start with EGA are for EGA. Use the following command
(after compiling BMPCNV.C) to view:
VGA monitors: EGA monitors:
BMPCNV /D VGABMP1 BMPCNV /D /B:14 EGABMP1
****************************************************************************/
#include <scl1.h>
#include <stdlib.h>
/* structures used by to define BMP file header */
typedef unsigned int WORD;
typedef unsigned long DWORD;
typedef struct{
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
}BITMAPFILEHEADER;
typedef struct{
DWORD biSize;
DWORD biWidth;
DWORD biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
DWORD biXPelsPerMeter;
DWORD biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
}BITMAPINFOHEADER;
char HelpText[]= "Converts a bitmap file to a character definition table that can\n"
"be used to modify EGA/VGA characters set.\n\n"
"BMPCNV [/B:bytes] INFILE[.BMP] [OUTFILE[.C]]\n\n"
"/B:bytes specifies the number of bytes per character definition\n"
" values range from 8 to 32 (default = 16)\n"
"INFILE[.BMP] valid bitmap file to be converted\n"
"[OUTFILE[.C]] output file created, if not specified BMPCNV\n"
" will use the name of the input file\n"
"/D Displays the bitmap, does not create output file\n";
main(int argc,char **argv)
{
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
LLData lld;
unsigned int bitbytes;
int tchars,tcols,tlines,line,col,scanline,points=16,display=0,schar;
unsigned char *p;
int i,i2,j,k;
unsigned int mask;
int handle;
char buffer[256];
char infile[80];
char outfile[80];
unsigned char NewChar[16];
printf("\n\nBITMAP conversion utility (C) 1991 by J. R. Alvira\n\n");
/* process command line arguments */
if(argc < 2)
{
printf(HelpText);
exit(-1);
}
for(i=1,j=0;i < argc;++i)
{
if(*argv[i]=='/' || *argv[i]=='-')
{
if(*(argv[i]+1) == 'B' || *(argv[i]+1) == 'b')
{
if(*(argv[i]+2) == ':')
points=atoi(argv[i]+3);
else
points=atoi(argv[i]+2);
}
else if(*(argv[i]+1) == 'D' || *(argv[i]+1) == 'd')
display=1;
else if(*(argv[i]+1) == '?')
{
printf(HelpText);
exit(0);
}
else
printf("Ignoring unknown switch %c\n",*(argv[i]+1));
}
else if(j==0)
{
strcpy(infile,argv[i]);
AddExtension(infile,"BMP");
++j;
}
else
{
strcpy(outfile,argv[i]);
AddExtension(outfile,"C");
++j;
}
}
if(points < 8 || points > 32)
{
printf("Illegal bytes value (8-32)\n");
exit(-1);
}
if(j == 1)
{
strcpy(outfile,infile);
ChangeExtension(outfile,"C");
}
if(OpenFile(infile,&handle,DOS2_RW))
{
printf("\nUnable to open %s\n\n",infile);
exit(-1);
}
if(ReadFile(handle,(char *)&bfh,sizeof(BITMAPFILEHEADER)))
{
CloseFile(handle);
printf("Error reading file header\n");
exit(-1);
}
if(bfh.bfType != 0x4d42)
{
CloseFile(handle);
printf("Not a valid bitmap file\n");
exit(-1);
}
if(ReadFile(handle,(char *)&bih,sizeof(BITMAPINFOHEADER)))
{
CloseFile(handle);
printf("Error reading info header\n");
exit(-1);
}
if(bih.biCompression)
{
CloseFile(handle);
printf("Bitmat data is compressed, cannot handle compressed format.\n");
exit(-1);
}
if((int)(bih.biWidth % 8))
{
CloseFile(handle);
printf("Bitmat width in pixels must be multiple of eight\n");
exit(-1);
}
if((int)(bih.biHeight % points))
{
CloseFile(handle);
printf("Bitmat height in pixels must be multiple of the number of bytes per character.\n");
exit(-1);
}
/* calculate number of character columns (8 bits) and lines using
BMP header information */
tcols=(int)(bih.biWidth / 8);
tlines=(int)(bih.biHeight / points);
tchars=tcols * tlines;
/* calculate total number of bytes with bitmap data */
bitbytes=(unsigned int)(bfh.bfSize - bfh.bfOffBits);
printf("%i bytes of bitmap data\n",bitbytes);
printf("Creating %i characters, %i bytes each (%i columns-%i lines)\n",tchars,points,tcols,tlines);
printf("Width in pixels: %li\n",bih.biWidth);
printf("Height in pixels: %li\n",bih.biHeight);
p=(unsigned char *)calloc(bitbytes,sizeof(char)); /* allocate buffer */
if(p==0)
{
printf("Not enough memory to read bitmap data\n");
CloseFile(handle);
exit(-1);
}
/* we'll use a linked list to process bitmap data */
LinkedList(LL_INIT,&lld);
lld.DataSize=sizeof(char) * points; /* size of each character */
/* create a linked list node for each character */
for(i=0;i < tchars;++i)
{
lld.Data=p;
if(LinkedList(LL_ADD,&lld)==LL_MEM_ERROR)
{
printf("Not enough memory to process bitmap data\n");
CloseFile(handle);
exit(-1);
}
}
/* move file pointer to the begining of bitmap data */
MoveFilePt2Offset(handle,bfh.bfOffBits);
if(ReadFile(handle,p,bitbytes)) /* read data */
{
printf("Unable to read bit data\n");
CloseFile(handle);
exit(-1);
}
/* conversion begins here */
mask=0x80;
LinkedList(LL_FIRST,&lld);
for(line=0;line < tlines;++line) /* process each character line */
{
LinkedList(LL_SAVE_POSITION,&lld);
for(scanline=points-1;scanline >= 0;--scanline) /* each scanline (pixel) */
{
for(col=0;col < tcols;++col) /* all characters in each line */
{
for(i=0,mask=0x80;i < 4;++i,++p)
{
if(((*p & 0xf0) >> 4))
*(lld.Data+scanline) |= mask;
mask >>= 1;
if((*p & 0x0f))
*(lld.Data+scanline) |= mask;
mask >>= 1;
}
LinkedList(LL_NEXT,&lld);
}
LinkedList(LL_RESTORE_POSITION,&lld);
}
for(i=0;i < tcols;++i)
LinkedList(LL_NEXT,&lld);
}
if(display==0) /* create file? */
{
if(CreateFile(outfile,&handle,F_ARCHIVE))
{
printf("Unable to write C source file\n");
CloseFile(handle);
exit(-1);
}
k=sprintf(buffer,"char CharDef[]={\r\n");
if(WriteFile(handle,buffer,k))
{
printf("Error writing C source file\n");
CloseFile(handle);
}
}
LinkedList(LL_LAST,&lld);
for(i=0;i < tcols-1;++i)
LinkedList(LL_PREVIOUS,&lld);
/* set video mode to correctly display bitmap */
VideoConfig();
if(display==1 && (VC_Monitor==VC_VGA || VC_Monitor==VC_EGA))
{
printf("Press any key to view bitmap...\n");
GetKey();
if(VC_Monitor==VC_VGA)
{
switch(points)
{
case 16:
SetVideoMode(3);
break;
case 14:
SetVideo28();
break;
case 8:
SetVideo4350();
break;
default:
display==-1;
break;
}
}
if(VC_Monitor==VC_EGA)
{
switch(points)
{
case 14:
SetVideoMode(3);
break;
case 8:
SetVideo4350();
break;
default:
display==-1;
break;
}
if(tchars > 32)
{
printf("Bitmap is too big to display\n");
display=0;
}
}
}
if(display==1)
SetCurPos(tlines+2,0);
else if(display==-1)
{
printf("Your monitor does not support the characters scanlines\n");
exit(-1);
}
for(i=0,schar=192;i < tlines;++i)
{
LinkedList(LL_SAVE_POSITION,&lld);
for(i2=0;i2 < tcols;++i2,++schar)
{
for(j=0,k=0;j < points;++j)
{
k+=sprintf(buffer+k,"0x%02x,",(unsigned int)(unsigned char)(lld.Data[j]));
if(display==1)
NewChar[j]=(unsigned char)(lld.Data[j]);
if(j==points-1)
{
if(i==tlines-1 && i2==tcols-1)
{
--k;
k+=sprintf(buffer+k,"};\r\n\r\n");
}
else
k+=sprintf(buffer+k,"\r\n");
}
}
if(display==1)
{
ModifyCharSet(points,schar,1,NewChar);
WriteChar(7,i,i2,1,schar);
}
else if(WriteFile(handle,buffer,k))
{
printf("Error writing C source\n");
CloseFile(handle);
}
LinkedList(LL_NEXT,&lld);
}
LinkedList(LL_RESTORE_POSITION,&lld);
for(j=0;j < tcols;++j)
LinkedList(LL_PREVIOUS,&lld);
}
if(display==1)
{
printf("Press any key...\n");
GetKey();
InitVideo();
}
else
{
if(CloseFile(handle))
{
printf("Error writing C source\n");
exit(-1);
}
else
printf("File %s has been created\n",outfile);
}
}